package spring.cloud.tasks.executor.service.impl;

import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import spring.cloud.tasks.common.util.DateUtils;
import spring.cloud.tasks.executor.service.PauseOrResumeScheduleTaskService;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;


public class PauseOrResumeScheduleTaskServiceImpl implements PauseOrResumeScheduleTaskService {
    /**
     * 任务的守护线程池
     */
    private static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(50);

    private static Map<String, ScheduledFuture> pauseOrResumeScheduleTaskIdToScheduledFutureMap = new HashMap<>();
    private Interner<String> weakInterner = Interners.newWeakInterner();

    @Override
    public void init(PauseOrResumeScheduleTask pauseOrResumeScheduleTask, Date nextTime) {
        pauseOrResumeScheduleTaskIdToScheduledFutureMap.put(pauseOrResumeScheduleTask.getId(), null);
        ScheduledFuture scheduledFuture = this.schedule(pauseOrResumeScheduleTask, nextTime);
        pauseOrResumeScheduleTaskIdToScheduledFutureMap.put(pauseOrResumeScheduleTask.getId(), scheduledFuture);
    }

    @Override
    public ScheduledFuture schedule(PauseOrResumeScheduleTask pauseOrResumeScheduleTask, Date nextTime) {
        synchronized (weakInterner.intern(pauseOrResumeScheduleTask.getId())) {
            if (pauseOrResumeScheduleTaskIdToScheduledFutureMap.containsKey(pauseOrResumeScheduleTask.getId())) {
                return scheduledExecutorService.schedule(pauseOrResumeScheduleTask, (nextTime.getTime() - DateUtils.now().getTime()), TimeUnit.MILLISECONDS);
            }
        }
        return null;
    }

    @Override
    public void cancel(PauseOrResumeScheduleTask pauseOrResumeScheduleTask) {
        synchronized (weakInterner.intern(pauseOrResumeScheduleTask.getId())) {
            if (pauseOrResumeScheduleTaskIdToScheduledFutureMap.containsKey(pauseOrResumeScheduleTask.getId())) {
                ScheduledFuture scheduledFuture = pauseOrResumeScheduleTaskIdToScheduledFutureMap.remove(pauseOrResumeScheduleTask.getId());
                if (scheduledFuture != null) {
                    scheduledFuture.cancel(true);
                }
            }
        }
    }
}
